package com.xjgc.msibase.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjgc.convert.param.ConvertParam;
import com.xjgc.convert.param.ConvertParamFactory;
import com.xjgc.msibase.constant.Constant;
import com.xjgc.msibase.entity.MsiExoServer;
import com.xjgc.msibase.entity.MsiExoTask;
import com.xjgc.msibase.entity.MsiExoTaskRecord;
import com.xjgc.msibase.mapper.MsiExoTaskMapper;
import com.xjgc.msibase.mapper.MsiExoTaskServerMapper;
import com.xjgc.msibase.service.IMsiExoServerService;
import com.xjgc.msibase.service.IMsiExoTaskRecordService;
import com.xjgc.msibase.service.IMsiExoTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.jeecg.common.api.vo.Result;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 外围服务接口
 *
 * @Description: 外围服务接口
 * @Author: 小逗号
 * @Date: 2023-10-30
 * @Version: V1.0
 */
@Slf4j
@Service
public class MsiExoTaskServiceImpl extends ServiceImpl<MsiExoTaskMapper, MsiExoTask>
        implements IMsiExoTaskService {
    @Resource
    private MsiExoTaskServerMapper msiExoTaskServerMapper;
    @Resource
    private IMsiExoServerService msiExoServerService;
    @Resource
    private IMsiExoTaskRecordService msiExoTaskRecordService;

    @Override
    public IPage<MsiExoTask> queryPage(IPage<MsiExoTask> page, MsiExoTask queryAo) {
        return baseMapper.selectPage(page, queryAo);
    }

    @Override
    public Result<?> execute(MsiExoTask exoTask, String dataText) {
        String taskName = exoTask.getTaskName();
        log.info("分发任务:{}  {}", taskName, exoTask.getTaskDesc());
        log.info("1.根据任务id查询外部接口");

        List<MsiExoServer> exoServerList = msiExoTaskServerMapper.selectByTaskId(exoTask.getId());
        if (CollectionUtils.isEmpty(exoServerList)) {
            return Result.error(taskName + "未关联下发接口!");
        }


        //任务定义的数据类型,即上游传递来的数据格式
        String dataType = exoTask.getDataType();
        //参数类:暂时使用参数类+XStream完成 json <=> xml 格式转换
        String paramBean = exoTask.getParamBean();
        //WS接口
        List<MsiExoServer> exoServerWsList = exoServerList.stream().filter(e -> Constant.SERVER_TYPE_WS.equals(e.getExoServerType())).collect(Collectors.toList());
        //REST接口
        List<MsiExoServer> exoServerRestList = exoServerList.stream().filter(e -> Constant.SERVER_TYPE_REST.equals(e.getExoServerType())).collect(Collectors.toList());
        log.info("保存任务执行记录!");
        MsiExoTaskRecord taskRecord = new MsiExoTaskRecord(exoTask, dataText);
        msiExoTaskRecordService.save(taskRecord);

        //...
        if (CollectionUtils.isNotEmpty(exoServerWsList)) {
            String dataAsXml;
            if (Constant.DATA_TYPE_JSON.equals(dataType)) {
                log.info("分发接口有WS数据为json,开启数据格式转换json-->xml");
                log.debug("json:{}", dataText);
                ConvertParam convertParam = ConvertParamFactory.parseJson(exoTask.getParamBean(), dataText);
                dataAsXml = ConvertParamFactory.toXml(exoTask, convertParam);
                log.debug("xml:{}", dataAsXml);
            } else if (Constant.DATA_TYPE_XML.equals(dataType)) {
                dataAsXml = dataText;
            } else {
                return Result.error(dataType + "未定义的数据格式!");
            }
            log.info("调用异步方法,请求外部WS接口!");
            for (MsiExoServer exoServer : exoServerWsList) {
                msiExoServerService.request(exoServer, taskRecord, dataAsXml);
            }
        }
        if (CollectionUtils.isNotEmpty(exoServerRestList)) {
            String dataAsJson;
            if (Constant.DATA_TYPE_XML.equals(dataType)) {
                log.info("分发接口有REST数据为xml,开启数据格式转换xml-->json");
                log.debug("xml:{}", dataText);
                ConvertParam<Serializable> convertParam = ConvertParamFactory.parseXml(exoTask, dataText);
                dataAsJson = JSON.toJSONString(convertParam);
                log.debug("json:{}", dataAsJson);
            } else if (Constant.DATA_TYPE_JSON.equals(dataType)) {
                dataAsJson = dataText;
            } else {
                return Result.error(dataType + "未定义的数据格式!");
            }

            log.info("调用异步方法,请求外部REST接口!");
            for (MsiExoServer exoServer : exoServerWsList) {
                msiExoServerService.request(exoServer, taskRecord, dataAsJson);
            }
        }
        /*
         * TODO 后期改造,多线程分发,然后汇总分发结果,再同步反馈调用方
         * */
        return Result.OK("数据正在分发,请稍后查看分发记录!");
    }

    @Override
    public <T extends Serializable> Result<?> execute(MsiExoTask exoTask, List<T> dataList) {
        return null;
    }
}
